﻿
namespace Mulala.Cavan.Core.Storage
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.Linq;
    using System.Threading;
    using System.Web;
    using System.Web.Caching;
    using System.Web.SessionState;
    using Mulala.Cavan.Core.Extension;

    public class SessionStorage : ISessionStorage
    {
        #region members
        int _minutesTeExpire = 60;
        #endregion members

        public virtual HttpContextBase HttpContextBase { protected get; set; }

        public virtual HttpSessionState Session { protected get; set; }

        public virtual Cache Cache { protected get; set; }

        public virtual HttpContext HttpContext
        {
            set
            {
                if (value.IsNull())
                {
                    return;
                }
                if (value.Session.Is())
                {
                    Session = value.Session;
                    return;
                }
                if (value.Cache.Is())
                {
                    Cache = value.Cache;
                    return;
                }
                Cache = HttpRuntime.Cache;
            }
        }


        public virtual int MinutesTeExpire
        {
            protected get { return _minutesTeExpire; }
            set { _minutesTeExpire = value; }
        }

        #region ISessionStorage Members
        public virtual object this[string key]
        {
            get
            {
                if (HttpContextBase.Is()
                    &&
                    HttpContextBase.Session.Is())
                {
                    return HttpContextBase.Session[UniqueIdentifier(key)];
                }

                Contract.Assert(Cache.Is() || Session.Is(), "no cache or session was provided");
                if (Cache.Is())
                {
                    Session = null;
                    return Cache[UniqueIdentifier(key)];
                }
                return Session[UniqueIdentifier(key)];
            }
            set
            {
                if (HttpContextBase.Is()
                    &&
                    HttpContextBase.Session.Is())
                {
                    HttpContextBase.Session[UniqueIdentifier(key)] = value;
                    return;
                }

                Contract.Assert(Cache.Is() || Session.Is(), "no cache or session was provided");
                if (Cache.Is())
                {
                    Cache.Insert(UniqueIdentifier(key), value, null, Cache.NoAbsoluteExpiration,
                        TimeSpan.FromMinutes(MinutesTeExpire));
                    return;
                }
                Session[UniqueIdentifier(key)] = value;
            }
        }

        public virtual void Clear()
        {
            if (HttpContextBase.Is()
                && HttpContextBase.Session.Is())
            {
                HttpContextBase.Session.Clear();
                return;
            }
            Session.Clear();
        }
        #endregion

        protected virtual string UniqueIdentifier(string key)
        {
            return Thread.CurrentPrincipal.Identity.Name + "|" + key;
        }
    }
}